home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / cross / Avr.lha / Atmel / INCCT_Programmer / Src / incct.c < prev    next >
C/C++ Source or Header  |  1999-11-02  |  11KB  |  580 lines

  1. /*************************************************************************/
  2. /* ATMEL microcontroller, in circuit programmer.                         */
  3. /* The input file should be a Motorola S19 Record.                       */
  4. /*************************************************************************/
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <exec/types.h>
  10.  
  11. #include "progress.h"
  12. #include "globdefs.h"
  13.  
  14. unsigned char PORT=0;
  15.  
  16. #define  BUSY    1       /*Bit value of busy line*/
  17. #define  DATA    1
  18. #define  CLOCK   2
  19. #define  RESET   4
  20.  
  21. #define  DATA_REG   ((BYTE*)0xBFE101L)
  22. #define  STAT_REG   ((BYTE*)0xBFD000L)
  23.  
  24. #define  DATA_LINE_HIGH  PORT|=DATA;  Out(DATA_REG,PORT)
  25. #define  DATA_LINE_LOW   PORT&=~DATA; Out(DATA_REG,PORT)
  26. #define  DATAIN          (In(STAT_REG) & BUSY)
  27.  
  28. #define CLOCK_HIGH  PORT|=CLOCK; Out(DATA_REG,PORT)     /*clock high*/
  29. #define CLOCK_LOW   PORT&=~CLOCK; Out(DATA_REG,PORT)    /*clock low*/
  30. #define RESET_HIGH  PORT|=RESET; Out(DATA_REG,PORT)
  31. #define RESET_LOW   PORT&=~RESET; Out(DATA_REG,PORT)
  32.  
  33. #define PROGRAM_ENABLE 0xAC530000UL
  34. #define CHIP_ERASE     0xAC800000UL
  35. #define LOCK_CHIP             0xACE00000UL
  36.  
  37. #define LOCK        1
  38. #define READ        2
  39.  
  40. #define MAX_SR_LINE 16      /*16 bytes max on one S Record line*/
  41.  
  42. struct SData {
  43.                              BYTE *Buffer;
  44.                              int  BufferSize;
  45.                              UWORD Address;
  46.                              int  LineType;
  47.                          };
  48.  
  49. BYTE SRBuffer[MAX_SR_LINE];
  50. BYTE SROffset;
  51.  
  52. void SendByte(ULONG Data, BYTE BitCount);
  53. void Out(BYTE *Port, BYTE data);
  54. BYTE In(BYTE *Port);
  55. BYTE GetVal();
  56. void Clock();
  57. BYTE ReadProgramMemory(ULONG Address, BYTE High);
  58. void WriteProgramMemory(ULONG Address, BYTE Data, BYTE High);
  59. int ParseSLine(FILE *Infile, struct SData *Info);
  60. BYTE HexToByte(char *Hex);
  61. void Reset_High();
  62. void Reset_Low();
  63. void Data_Low();
  64. void Data_High();
  65. void Clock_Low();
  66. void Clock_High();
  67. ULONG GetDeviceCode();
  68. void ReadFlash(FILE *Outfile,int Size);
  69. void delay(int Milliseconds);
  70. ULONG SRecordSize(FILE *Record);
  71. int FinishSRecord(FILE *F,int PC);
  72. int FlushSRBuffer(FILE *Outfile,int PC);
  73. int PutSRBuffer(FILE *File, BYTE Data, int PC);
  74. int StartSRecord(FILE *File, char *Name);
  75.  
  76. int Program_It(int argc, char *argv[])
  77. {
  78.     FILE *Infile;
  79.   ULONG Size, ByteCounter=0;
  80.     WORD Address;
  81.     BYTE Data, Check, OldPort, OldStatus;
  82.     struct SData SLine;
  83.     int Os, High, Try, RRes;
  84.     BYTE Flags=0;
  85.     ULONG DeviceCode;
  86.     char *Sizes[]={"1K","2K","4K","8K","?"};
  87.     int MemBytes[]={1024,2048,4096,8192};
  88.  
  89.   printf("\nINCCT "VERSION" ©1999 LJS By Lee Atkins.\nATMEL in circuit programmer.\n");
  90.  
  91.   if(strchr(argv[1],'?'))
  92.     {
  93.         printf("\nINCCT <filename> [options]");
  94.         printf("\noptions:\n-l  Lock device.\n");
  95.         printf("-r  Read Flash to <filename>\n");
  96.     printf("-ee Write <filename> to EEPROM.\n");
  97.     printf(" No arguments starts GUI.\n\n");
  98.         return 0;
  99.     }
  100.  
  101.     for(Try=1; Try<argc; Try++)
  102.     {
  103.         if(strcmp(argv[Try],"-l")==0) Flags|=LOCK;
  104.         if(strcmp(argv[Try],"-r")==0) Flags|=READ;
  105.     if(strcmp(argv[Try],"-ee")==0)
  106.     {
  107.       printf("Not done!\n");
  108.       return 0;
  109.     }
  110.     }
  111.  
  112.     if(Flags&READ)
  113.     {
  114.         Infile=fopen(argv[1],"wb");
  115.     }
  116.     else
  117.     {
  118.         Infile=fopen(argv[1],"r");      /*Only text (Motorola S record)*/
  119.     }
  120.  
  121.     if (Infile==NULL)
  122.     {
  123.         printf("Can't open %s\n",argv[1]);
  124.         return 0;;
  125.     }
  126.  
  127.   OldPort=*((BYTE*)0xBFE301L);    /*Save old port state*/
  128.   OldStatus=*((BYTE*)0xBFD200L);
  129.   *((BYTE*)0xBFE301L)=0xFF;      /*Set new port state*/
  130.  
  131.   *((BYTE*)0xBFD200L)=OldStatus&(~BUSY); 
  132.   
  133.     Out(DATA_REG,0);
  134.     delay(1);
  135.     Reset_High();
  136.     delay(100);
  137.     Reset_Low();
  138.     delay(100);
  139.     if(!(Flags&READ))
  140.     {
  141.     Size=SRecordSize(Infile);    
  142.         SendByte(PROGRAM_ENABLE,32);
  143.         SendByte(CHIP_ERASE,32);
  144.         delay(100);                                                /*wait for processor to finish whatever.*/
  145.  
  146.         Reset_High();
  147.         Reset_Low();
  148.         delay(40);
  149.     }
  150.     SendByte(PROGRAM_ENABLE,32);
  151.  
  152.     DeviceCode=GetDeviceCode();
  153.     printf("Device code : 0x%08lX\n",DeviceCode);
  154.     printf("Manufacturer:");
  155.     if((DeviceCode&0xFF000000UL)==0x1E000000UL)
  156.     {
  157.      printf("ATMEL\n");
  158.     }
  159.     else
  160.     {
  161.         printf("Unknown\n");
  162.     }
  163.     printf("Flash size:");
  164.     printf("%s\n",Sizes[((DeviceCode&0x000F0000)>>16)<4 ? (DeviceCode&0x000F0000)>>16:4]);
  165.  
  166.     if(Flags&READ)
  167.     {
  168.     if( ((DeviceCode&0x000F0000)>>16) <4)
  169.     {
  170.           ReadFlash(Infile,MemBytes[(DeviceCode&0x000F0000)>>16]);
  171.           fclose(Infile);
  172.           Reset_High();
  173.       *((BYTE*)0xBFE301L)=OldPort;
  174.       *((BYTE*)0xBFD200L)=OldStatus;
  175.   
  176.           return 1;
  177.     }
  178.     else
  179.     {
  180.       printf("Can't read device.\n");
  181.     }
  182.     }
  183.  
  184.     while( (RRes=ParseSLine(Infile,&SLine)) == 1 )
  185.     {
  186.         if (SLine.LineType==0)
  187.         {
  188.             printf("S record name : ");
  189.             printf("%s\nProgramming....",SLine.Buffer);
  190.         }
  191.         else if(SLine.LineType==1)
  192.         {
  193.             Os=0;
  194.             while(SLine.BufferSize)
  195.             {
  196.                 Try=5;
  197.                 do
  198.                 {
  199.                     WriteProgramMemory(SLine.Address>>1,*(SLine.Buffer+Os),SLine.Address&1);
  200.                     delay(4);
  201.                     Check=ReadProgramMemory(SLine.Address>>1,SLine.Address&1);
  202.                     Try--;
  203.                 }while((Check!=*(SLine.Buffer+Os)) && (Try));
  204.                 if(Try==0)
  205.                 {
  206.                     printf(" **** Device failed ****\n");
  207.  
  208.           FinishProgress();
  209.                     free(SLine.Buffer);
  210.                     fclose(Infile);
  211.                     Reset_High();
  212.           *((BYTE*)0xBFE301L)=OldPort;
  213.           *((BYTE*)0xBFD200L)=OldStatus;
  214.                     return 0;
  215.                 }
  216.  
  217.                 SLine.Address++;
  218.                 Os++;
  219.         ByteCounter++;
  220.                 SLine.BufferSize--;
  221.         Progress(ByteCounter,Size);   /*Display progress bar*/
  222.             }
  223.         }
  224.         free(SLine.Buffer);
  225.     }
  226.  
  227.   FinishProgress();       /*Close progress bar*/
  228.  
  229.   if(RRes==2)
  230.   {
  231.     free(SLine.Buffer);
  232.       fclose(Infile);
  233.       if(Flags&LOCK)
  234.       {
  235.           SendByte(LOCK_CHIP,32);
  236.           printf("Device locked.\n");
  237.       }
  238.  
  239.       printf("\nFinished.\n");
  240.       Reset_High();
  241.     *((BYTE*)0xBFE301L)=OldPort;
  242.     *((BYTE*)0xBFD200L)=OldStatus;
  243.     return 1;
  244.   }
  245.   else
  246.   {
  247.     printf("S Record error!\n");
  248.   }
  249.   fclose(Infile);
  250.   *((BYTE*)0xBFE301L)=OldPort;
  251.   *((BYTE*)0xBFD200L)=OldStatus;
  252.   
  253.   return 0;
  254. }/*end*/
  255.  
  256. void SendByte(ULONG Data, BYTE BitCount)
  257. {
  258.      /*Sends data to the processor, serialy*/
  259.  /* 'BitCount' bits from 'Data' will be sent , MSB first*/
  260.  while(BitCount)
  261.  {
  262.      Clock_Low();
  263.      if (Data & 0x80000000UL)
  264.      {
  265.          Data_High();
  266.      }
  267.      else
  268.      {
  269.          Data_Low();
  270.      }
  271.      Clock_High();
  272.    Data<<=1;
  273.      BitCount--;
  274.  }
  275.  Clock_Low();
  276. }
  277.  
  278. BYTE GetByte()
  279. {
  280.  BYTE Weight=0x80;
  281.  BYTE Result=0, Count=8;
  282.  
  283.  /*gets data from the processor, serialy*/
  284.  /* MSB first*/
  285.  
  286.  while(Count)
  287.  {
  288.      Clock_Low();
  289.      if (DATAIN)
  290.      {
  291.          Result|=Weight;
  292.      }
  293.      else
  294.      {
  295.      }
  296.      Weight>>=1;
  297.    Weight&=127;
  298.      Count--;
  299.      Clock_High();
  300.  }
  301.  Clock_Low();
  302.  
  303.  return Result;
  304. }
  305.  
  306. void Out(BYTE *Port, BYTE data)
  307. {
  308.   *Port=data;
  309. }
  310.  
  311. BYTE In(BYTE *Port)
  312. {
  313.   return (*Port);
  314. }
  315.  
  316. void Data_Low()
  317. {
  318.     DATA_LINE_LOW;
  319. }
  320.  
  321. void Data_High()
  322. {
  323.     DATA_LINE_HIGH;
  324. }
  325.  
  326. void Clock_Low()
  327. {
  328.     CLOCK_LOW;
  329.   CLOCK_LOW;
  330. }
  331.  
  332. void Clock_High()
  333. {
  334.  CLOCK_HIGH;
  335.  CLOCK_HIGH;
  336.  CLOCK_HIGH;
  337. }
  338.  
  339. void Reset_Low()
  340. {
  341.     RESET_LOW;
  342. }
  343.  
  344. void Reset_High()
  345. {
  346.     RESET_HIGH;
  347. }
  348.  
  349. BYTE ReadProgramMemory(ULONG Address, BYTE High)
  350. {
  351.     /*reads either the high (High=1) byte or low byte (High=0) from an address.*/
  352.  
  353.     ULONG Command;
  354.  
  355.     if (High)
  356.     {
  357.         Command=0x28;
  358.     }
  359.     else
  360.     {
  361.         Command=0x20;
  362.     }
  363.     Command<<=24;
  364.             /* Command = 0x28000000 or 0x20000000*/
  365.     Address<<=8;
  366.     Address&=0x0007ff00UL;
  367.     Command|=Address;
  368.     SendByte(Command,24);        /*move the command and address to the chip.*/
  369.     return GetByte();
  370. }
  371.  
  372. void WriteProgramMemory(ULONG Address, BYTE Data, BYTE High)
  373. {
  374.     /*reads either the high (High=1) byte or low byte (High=0) from an address.*/
  375.  
  376.     ULONG Command;
  377.  
  378.     if (High)
  379.     {
  380.         Command=0x48000000;
  381.     }
  382.     else
  383.     {
  384.         Command=0x40000000;
  385.     }
  386.             /* Command = 0x48000000 or 0x40000000*/
  387.     Address<<=8;
  388.     Address&=0x0007ff00UL;
  389.     Command|=Address;
  390.     Command|=(Data&0xFF);
  391.  
  392.     SendByte(Command,32);  /*move the command, address and data to the chip.*/
  393. }
  394.  
  395. BYTE HexToByte(char *Hex)
  396. {
  397.     /*assumes valid hex*/
  398.     int Result=0;
  399.     Result=(*Hex<'A' ? *Hex-'0':10+(*Hex-'A'));
  400.     Result*=16;
  401.     Hex++;
  402.     Result+=(*Hex<'A' ? *Hex-'0':10+(*Hex-'A'));
  403.     return Result;
  404. }
  405.  
  406. int ParseSLine(FILE *Infile, struct SData *Info)
  407. {
  408.     BYTE Temp[80], Hex[2], Result, *Buffer=NULL,Ret=1;
  409.     int Offset, ByteCount, ResultOs=0;
  410.  
  411.     if (fgets(Temp,80,Infile))
  412.     {
  413.     if(Temp[0]!='S')
  414.     {
  415.       return 0;
  416.     }
  417.         Info->LineType=Temp[1]-0x30;
  418.     if(Info->LineType==9)
  419.     {
  420.       Ret=2;
  421.     }
  422.         Offset=2;
  423.         Hex[0]=Temp[Offset++];
  424.         Hex[1]=Temp[Offset++];
  425.         ByteCount=HexToByte(Hex);
  426.         ByteCount-=3;                                /*2 bytes address, 1 check.*/
  427.         Buffer=(BYTE*)malloc(ByteCount+1);
  428.         if (Buffer==NULL)
  429.         {
  430.             return 0;
  431.         }
  432.         Info->BufferSize=ByteCount;
  433.         Hex[0]=Temp[Offset++];        /*Get address.*/
  434.         Hex[1]=Temp[Offset++];
  435.         Result=HexToByte(Hex);
  436.         Info->Address=Result;
  437.         Info->Address<<=8;
  438.  
  439.         Hex[0]=Temp[Offset++];
  440.         Hex[1]=Temp[Offset++];
  441.         Info->Address|=HexToByte(Hex)&0xFF;
  442.         while(ByteCount)
  443.         {
  444.             Hex[0]=Temp[Offset++];
  445.             Hex[1]=Temp[Offset++];
  446.             Result=HexToByte(Hex);
  447.             *(Buffer+ResultOs)=Result;
  448.             ResultOs++;
  449.             ByteCount--;
  450.         }
  451.         *(Buffer+ResultOs)=0;
  452.         Info->Buffer=Buffer;
  453.         return Ret;
  454.     }
  455.     return 0;
  456. }
  457.  
  458. ULONG GetDeviceCode()
  459. {
  460.     int Address=0;
  461.     ULONG Command=0x30000000UL, Result=0;
  462.     int Count;
  463.  
  464.     for(Count=0; Count<3; Count++)
  465.     {
  466.         SendByte(Command|(Address<<8),24);
  467.         Result|=(GetByte()&0xFF);
  468.         Result<<=8;
  469.     Address++;
  470.     }
  471.     return Result;
  472. }
  473.  
  474. void ReadFlash(FILE *Outfile,int Size)
  475. {
  476.     int Address;
  477.     BYTE Check;
  478.  
  479.   StartSRecord(Outfile,"FLASH");
  480.  
  481.     for(Address=0; Address<Size; Address++)
  482.     {
  483.       Check=ReadProgramMemory(Address>>1,Address&1);
  484.     PutSRBuffer(Outfile,Check,Address);
  485.     }
  486.   FinishSRecord(Outfile,Address);
  487. }
  488.  
  489. ULONG SRecordSize(FILE *Record)
  490. {
  491.   ULONG Result=0;
  492.   struct SData SLine;
  493.  
  494.   while(ParseSLine(Record,&SLine))
  495.   {
  496.     if(SLine.LineType==1)
  497.     {
  498.       Result+=SLine.BufferSize;
  499.     }
  500.     free(SLine.Buffer);
  501.   }
  502.   fseek(Record, 0, SEEK_SET);
  503.   return Result;
  504. }
  505.  
  506. int StartSRecord(FILE *File, char *Name)
  507. {
  508.     int Checksum, Temp;
  509.     char *Orig;
  510.  
  511.     Orig=Name;
  512.     fprintf(File,"S0");
  513.     Temp=0;
  514.     while( (*Name) && (*Name!='.') )
  515.     {
  516.         Temp++;
  517.         Name++;
  518.     }
  519.     Name=Orig;
  520.     Temp+=3;      /*+address +checksum*/
  521.     Checksum=Temp;
  522.     fprintf(File,"%02X",Temp);
  523.     fprintf(File,"0000");
  524.     while( (*Name) && (*Name!='.') )
  525.     {
  526.         fprintf(File,"%02X",*Name);
  527.         Checksum+=*Name;
  528.         Name++;
  529.     }
  530.     Checksum=~Checksum;
  531.     fprintf(File,"%02X\n",(Checksum&255));
  532.     SROffset=0;
  533.     return 1;
  534. }
  535.  
  536. int PutSRBuffer(FILE *File, BYTE Data, int PC)
  537. {
  538.     SRBuffer[SROffset]=Data;
  539.     SROffset++;
  540.     if(SROffset==MAX_SR_LINE)
  541.     {
  542.         FlushSRBuffer(File,PC);
  543.     }
  544.     return 1;
  545. }
  546.  
  547. int FlushSRBuffer(FILE *Outfile,int PC)
  548. {
  549.     int C,Count;
  550.     int Checksum;
  551.  
  552.     Count=SROffset;
  553.     if(Count==0)
  554.     {
  555.         return 1;
  556.     }
  557.     fprintf(Outfile,"S1");
  558.     fprintf(Outfile,"%02X",(Count+3)&255);  /*+3 for checksum and address*/
  559.     Checksum=Count+3;
  560.     fprintf(Outfile,"%04X",PC-Count+1);
  561.     Checksum+=((PC-Count+1)>>8);
  562.     Checksum+=((PC-Count+1)&255);
  563.     for(C=0; C<Count; C++)
  564.     {
  565.         fprintf(Outfile,"%02X",SRBuffer[C]&255);
  566.         Checksum+=SRBuffer[C];
  567.     }
  568.     Checksum=~Checksum;
  569.     fprintf(Outfile,"%02X\n",(Checksum&255));
  570.     SROffset=0;
  571.     return 1;
  572. }
  573.  
  574. int FinishSRecord(FILE *F,int PC)
  575. {
  576.      FlushSRBuffer(F,PC);
  577.      fprintf(F,"S9030000FC\n");
  578.      return 1;
  579. }
  580.